package com.guaoran.interview.spring.scope.controller;

import com.guaoran.interview.InterviewApplication;
import com.guaoran.interview.spring.scope.service.*;
import org.springframework.beans.BeansException;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.annotation.ApplicationScope;
import org.springframework.web.context.annotation.RequestScope;
import org.springframework.web.context.annotation.SessionScope;

import java.util.ArrayList;
import java.util.List;

/**
 * @author : 孤傲然
 * @description : scope
 * @date :2020/1/2 13:32
 */
@RestController
public class ScopeController implements ApplicationContextAware {
    // spring 中的作用域常用的有 singleton 、prototype 、 request 、 session 、 application
    private ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }


    private static List<SessionService> sessionServices = new ArrayList<>();
    private static List<RequestService> requestServices = new ArrayList<>();
    private static List<ApplicationService> applicationServices = new ArrayList<>();

    @GetMapping("/")
    public String get(){
        /**
         * 单例级别的作用域 默认 {@link ConfigurableBeanFactory.SCOPE_SINGLETON} 在IOC容器中，只会存在一个bean， 当IOC容器关闭是，会进行销毁
         */
        SingletonService singletonService = applicationContext.getBean(SingletonService.class);
        SingletonService singletonService2 = applicationContext.getBean(SingletonService.class);
        System.out.println(singletonService==singletonService2);


        /**
         * 原型级别的作用域  {@link ConfigurableBeanFactory.SCOPE_PROTOTYPE} ,每次会话都会生成一个bean， spring不会对原型的bean的生命周期进行管理
         */
        PrototypeService prototypeService = applicationContext.getBean(PrototypeService.class);
        PrototypeService prototypeService2 = applicationContext.getBean(PrototypeService.class);
        System.out.println(prototypeService==prototypeService2);




        SessionService sessionService = applicationContext.getBean(SessionService.class);
        SessionService sessionService2 = applicationContext.getBean(SessionService.class);
        System.out.println(sessionService==sessionService2);


        RequestService requestService = applicationContext.getBean(RequestService.class);
        RequestService requestService2 = applicationContext.getBean(RequestService.class);
        System.out.println(requestService==requestService2);


        ApplicationService applicationService = applicationContext.getBean(ApplicationService.class);
        ApplicationService applicationService2 = applicationContext.getBean(ApplicationService.class);

        testRequest(requestService,requestService2);
        testSession(sessionService,sessionService2);
        testApplication(applicationService,applicationService2);


        LookUpService lookUpService = applicationContext.getBean(LookUpService.class);
        LookUpService lookUpService2 = applicationContext.getBean(LookUpService.class);
        lookUpService.uuid();
        lookUpService2.uuid();

        LazyService lazyService = applicationContext.getBean(LazyService.class);

        return null;
    }

    /**
     * request 级别的作用域 {@link RequestScope} 每次请求会生成一个bean，请求结束后会对生成的bean进行销毁
     * @param requestService
     * @param requestService2
     */
    public void testRequest(RequestService requestService,RequestService requestService2){
        RequestService requestService3 = applicationContext.getBean(RequestService.class);
        RequestService requestService4 = applicationContext.getBean(RequestService.class);
        requestServices.add(requestService);
        requestServices.add(requestService2);
        requestServices.add(requestService3);
        requestServices.add(requestService4);

    }

    /**
     * session 级别的作用域 {@link SessionScope} 每个不同的session中会生成一个bean， session过期后会对生成的bean进行销毁
     * @param sessionService
     * @param sessionService2
     */
    public void testSession(SessionService sessionService,SessionService sessionService2){
        SessionService sessionService3 = applicationContext.getBean(SessionService.class);
        SessionService sessionService4 = applicationContext.getBean(SessionService.class);
        sessionServices.add(sessionService);
        sessionServices.add(sessionService2);
        sessionServices.add(sessionService3);
        sessionServices.add(sessionService4);
    }

    /**
     * 类似单例bean，{@link ApplicationScope}
     * @param applicationService
     * @param applicationService2
     */
    public void testApplication(ApplicationService applicationService,ApplicationService applicationService2){
        ApplicationService applicationService3 = applicationContext.getBean(ApplicationService.class);
        ApplicationService applicationService4 = applicationContext.getBean(ApplicationService.class);
        applicationServices.add(applicationService);
        applicationServices.add(applicationService2);
        applicationServices.add(applicationService3);
        applicationServices.add(applicationService4);
    }

}
